package com.cxria.script.upload.dao.impl

import com.cxria.script.HibernateUtils
import com.cxria.script.upload.dao.IBaseDao
import com.cxria.script.upload.dao.support.Page
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query

import javax.transaction.Transactional;

class BaseDao<R> implements IBaseDao<R> {
    protected static final String SP = " ";
    protected static final String ORDER_BY = "Order By";
    SessionFactory sessionFactory;

    BaseDao() {
        def na = HibernateUtils.instance
        this.sessionFactory = na.sessionFactory
    }

    protected Session getSession() {
        return this.sessionFactory.openSession()
    }

    @Transactional
    void save(Object o) {
        this.getSession().save(o);
    }

    @Transactional
    void saveOrUpdate(Object object) {
        this.getSession().saveOrUpdate(object);
    }

    @Transactional
    void update(Object o) {
        this.getSession().update(o);
    }

    @Transactional(
//            readOnly = true
    )
    R get(Class<R> c, Serializable id) {
        return this.getSession().get(c, id);
    }

    @Transactional(
//            readOnly = true
    )
    <R> List<R> list(Class<R> c, String hql, Map<String, Object> params, Page page) {
        Query<R> query = this.getSession().createQuery(hql, c);
        params.forEach(query::setParameter);
        query.setFirstResult(page.getBeginNum());
        query.setMaxResults(page.getPageSize());
        List<R> resultList = query.list();
        String countHQL = "Select Count(*)";
        if (hql.contains("Order By")) {
            countHQL = countHQL + hql.substring(0, hql.indexOf("Order By"));
        } else {
            countHQL = countHQL + hql;
        }

        Query<Long> countQuery = this.getSession().createQuery(countHQL, Long.class);
        params.forEach(countQuery::setParameter);
        Long count = (Long)countQuery.uniqueResult();
        page.setTotal(count.intValue());
        return resultList;
    }
}

